home *** CD-ROM | disk | FTP | other *** search
- #
- # TCL Library for tkCVS
- #
-
- #
- # $Id: logcanvas.tcl,v 1.13 1995/11/13 05:16:55 davide Exp $
- #
- # Contains procedures used for the log canvas for tkCVS.
- #
-
- #
- # Globals used in drawing canvases
- #
-
- # Height and width to draw boxes
- set cvscanv(boxx) 60
- set cvscanv(boxy) 30
- # Gaps between boxes
- set cvscanv(gapx) [expr $cvscanv(boxx) + 10]
- set cvscanv(gapy) [expr $cvscanv(boxy) + 10]
- # Indent at top left of canvas
- set cvscanv(indx) 20
- set cvscanv(indy) 20
- # Static type variables used while drawing on the canvas.
- set cvscanv(nextx) $cvscanv(indx)
- set cvscanv(nexty) $cvscanv(indy)
- set cvscanv(indents) 0
- set cvscanv(xhigh) [expr $cvscanv(boxx) + $cvscanv(indx)]
- set cvscanv(yhigh) [expr $cvscanv(boxy) + $cvscanv(indy)]
- set cvscanv(xlow) 0
- set cvscanv(ylow) 0
-
- proc new_logcanvas {localfile filelog} {
- #
- # Creates a new log canvas. filelog must be the output of a cvs
- # log or rlog command. If localfile is not "no file" then it is
- # the file name in the local directory that this applies to.
- #
- global cvs
- global cvscanv
- global tagvalues
-
- static {canvasnum 0}
-
- # Make the canvas
-
- incr canvasnum
- set logcanvas ".logcanvas$canvasnum"
- toplevel $logcanvas
-
- frame $logcanvas.up -relief groove -border 2
- frame $logcanvas.up.left
- frame $logcanvas.up.right
- frame $logcanvas.up1 -relief groove -border 2
- frame $logcanvas.up1.left
- frame $logcanvas.up1.right
- frame $logcanvas.up2 -relief groove -border 2
- frame $logcanvas.up2.left
- frame $logcanvas.up2.right
- frame $logcanvas.down -relief groove -border 2
-
- pack $logcanvas.up -side top -fill x
- pack $logcanvas.up.left -side left -fill both
- pack $logcanvas.up.right -side left -fill both -expand 1
- pack $logcanvas.up1 -side top -fill x
- pack $logcanvas.up1.left -side left -fill both
- pack $logcanvas.up1.right -side left -fill both -expand 1
- pack $logcanvas.up2 -side top -fill x
- pack $logcanvas.up2.left -side left -fill both
- pack $logcanvas.up2.right -side left -fill both -expand 1
- pack $logcanvas.down -side bottom -fill x
-
- label $logcanvas.lfname -anchor w -text "RCS File Name"
- entry $logcanvas.tfname
- # This is a hidden entry that stores the local file name.
- entry $logcanvas.tlocalfile
- $logcanvas.tlocalfile delete 0 end
- $logcanvas.tlocalfile insert end $localfile
-
- label $logcanvas.lvers1 -anchor w -text "Version A"
- label $logcanvas.lwho1 -anchor w -text "Created by"
- label $logcanvas.ldate1 -anchor w -text "Date"
- label $logcanvas.lcomment1 -anchor w -text "Comment"
-
- entry $logcanvas.tvers1 -relief sunken
- label $logcanvas.twho1 -anchor w -text "--"
- label $logcanvas.tdate1 -anchor w -text "--"
- text $logcanvas.tcomment1 -height 5 -width 75
-
- label $logcanvas.lvers2 -anchor w -text "Version B"
- label $logcanvas.lwho2 -anchor w -text "Created by"
- label $logcanvas.ldate2 -anchor w -text "Date"
- label $logcanvas.lcomment2 -anchor w -text "Comment"
-
- entry $logcanvas.tvers2 -relief sunken
- label $logcanvas.twho2 -anchor w -text "--"
- label $logcanvas.tdate2 -anchor w -text "--"
- text $logcanvas.tcomment2 -height 5 -width 75
-
- pack $logcanvas.lfname \
- -in $logcanvas.up.left \
- -side top -fill x -pady 2
- pack $logcanvas.tfname \
- -in $logcanvas.up.right \
- -side top -fill x -pady 0
- pack $logcanvas.lvers1 $logcanvas.lwho1 $logcanvas.ldate1 $logcanvas.lcomment1 \
- -in $logcanvas.up1.left \
- -side top -fill x -pady 0
- pack $logcanvas.tvers1 $logcanvas.twho1 $logcanvas.tdate1 $logcanvas.tcomment1 \
- -in $logcanvas.up1.right \
- -side top -fill x -pady 0
- pack $logcanvas.lvers2 $logcanvas.lwho2 $logcanvas.ldate2 $logcanvas.lcomment2 \
- -in $logcanvas.up2.left \
- -side top -fill x -pady 0
- pack $logcanvas.tvers2 $logcanvas.twho2 $logcanvas.tdate2 $logcanvas.tcomment2 \
- -in $logcanvas.up2.right \
- -side top -fill x -pady 0
-
- canvas $logcanvas.canvas -relief sunken -border 2 \
- -yscrollcommand "$logcanvas.yscroll set" \
- -xscrollcommand "$logcanvas.xscroll set"
- scrollbar $logcanvas.xscroll -relief sunken -orient horizontal \
- -command "$logcanvas.canvas xview"
- scrollbar $logcanvas.yscroll -relief sunken \
- -command "$logcanvas.canvas yview"
-
- #
- # Create buttons
- #
-
- button $logcanvas.help -text "Help" \
- -command log_browser
- button $logcanvas.view -text "View" \
- -command "logcanvas_view $logcanvas"
- button $logcanvas.diff -text "Diff" \
- -command "logcanvas_diff $logcanvas"
- pack $logcanvas.help $logcanvas.view $logcanvas.diff \
- -in $logcanvas.down -side left \
- -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
- if {$localfile != "no file"} {
- button $logcanvas.join -text "Merge Branch to Head" \
- -command "logcanvas_join $localfile $logcanvas"
- button $logcanvas.delta -text "Merge Changes to Head" \
- -command "logcanvas_delta $localfile $logcanvas"
- pack $logcanvas.join $logcanvas.delta \
- -in $logcanvas.down -side left \
- -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
- }
- button $logcanvas.viewtags -text "View Tags" \
- -command "nop"
- button $logcanvas.quit -text "Quit" \
- -command "destroy $logcanvas"
- pack $logcanvas.viewtags $logcanvas.quit \
- -in $logcanvas.down -side left \
- -ipadx 2 -ipady 2 -padx 4 -pady 4 -fill both -expand 1
-
- #
- # Put the canvas on to the display.
- #
-
- pack $logcanvas.xscroll -side bottom -fill x -padx 2 -pady 2
- pack $logcanvas.yscroll -side right -fill y -padx 2 -pady 2
- pack $logcanvas.canvas -fill both -expand 1
-
- logcanvas_clear $logcanvas
-
- #
- # Window manager stuff.
- #
-
- wm title $logcanvas "CVS Log Browser"
- wm minsize $logcanvas 1 1
-
- # Draw the log onto the canvas.
- # Start by splitting the log up and parsing it using a simple
- # state machine.
-
- set loglist [split $filelog "\n"]
- set logstate "searching"
- set logstate "rcsfile"
- foreach logline $loglist {
- switch -exact -- $logstate {
- "rcsfile" {
- # Look for the first text line which should give the file name.
- set fileline [split $logline]
- if {[lindex $fileline 0] == "RCS"} {
- $logcanvas.tfname delete 0 end
- $logcanvas.tfname insert end [lindex $fileline 2]
- set logstate "tags"
- set taglist ""
- if [array exists tagvalues] {
- foreach item [array names tagvalues] {
- set tagvalues($item) ""
- }
- }
- continue
- }
- }
- "tags" {
- # Any line with a tab leader is a tag
- if { [string index $logline 0] == "\t" } {
- set taglist "$taglist$logline\n"
- set tagitems [split $logline ":"]
- set tagname [string trim [lindex $tagitems 0]]
- set tagrevision [string trim [lindex $tagitems 1]]
- set tagvalues($tagname) $tagrevision
- #puts "Tag $tagname is on revision $tagrevision"
- } else {
- if {$logline == "description:"} {
- # No more tags after this point
- $logcanvas.viewtags configure \
- -command "view_output Tags \"$taglist\""
- set logstate "searching"
- continue
- }
- if {$logline == "----------------------------"} {
- # Oops, missed something.
- $logcanvas.viewtags configure \
- -command "view_output Tags \"$taglist\""
- set logstate "revision"
- continue
- }
- }
- }
- "searching" {
- # Look for the line that starts a revision message.
- if {$logline == "----------------------------"} {
- set logstate "revision"
- continue
- }
- }
- "revision" {
- # Look for a revision number line
- set revline [split $logline]
- set revnum [lindex $revline 1]
- set logstate "date"
- }
- "date" {
- # Look for a date line. This also has the name of the author.
- set dateline [split $logline]
- set revdate [lindex $dateline 1]
- # set revtime [lindex $dateline 2]
- # set revtime [string range $revtime 0 [expr [string length $revtime] - 2]]
- set revwho [lindex $dateline 5]
- set revwho [string range $revwho 0 [expr [string length $revwho] - 2]]
- set logstate "logmessage"
- set revcomment ""
- }
- "logmessage" {
- # Read the log message which follows the date line.
- if {$logline == "----------------------------"} {
- set logstate "revision"
- # Draw the revision box on the canvas.
- # puts "Revision number $revnum by $revwho on $revdate at $revtime"
- logcanvas_draw_box $logcanvas $revnum $revwho $revdate $revcomment
- continue
- } elseif {$logline == "============================================================================="} {
- set logstate "terminated"
- # Draw the revision box on the canvas.
- # puts "Revision number $revnum by $revwho on $revdate at $revtime"
- logcanvas_draw_box $logcanvas $revnum $revwho $revdate $revcomment
- continue
- }
- # Process a revision log line
- regsub -all "\"" $logline "'" newline
- set revcomment "$revcomment$newline\n"
- }
- "terminated" {
- # ignore any further lines
- continue
- }
- }
- }
-
- # End of log file processing.
- }
-
- proc logcanvas_clear {logcanvas} {
- #
- # Clears the canvas and resets globals ready to re-draw.
- #
- global cvscanv
-
- set cvscanv(nextx) $cvscanv(indx)
- set cvscanv(nexty) $cvscanv(indy)
- set cvscanv(indents) 0
- set cvscanv(branches) {}
- set cvscanv(xhigh) [expr $cvscanv(boxx) + $cvscanv(indx)]
- set cvscanv(yhigh) [expr $cvscanv(boxy) + $cvscanv(indy)]
- # $logcanvas.canvas delete all
- }
-
- proc logcanvas_box_colour {revnum} {
- #
- # Determines what colour the box should be.
- #
- global cvscfg
- global tagvalues
-
- set return_colour black
-
- if [array exists tagvalues] {
- foreach item [array names tagvalues] {
- if [string match $tagvalues($item) $revnum] {
- if [info exists cvscfg(boxcolour,$item)] {
- set return_colour $cvscfg(boxcolour,$item)
- }
- }
- }
- }
- #puts "colour of $revnum is $return_colour"
- return $return_colour
- }
-
- proc logcanvas_dot_colour {revnum} {
- #
- # Determines what colour dots in the box should be.
- #
- global cvscfg
- global tagvalues
-
- set return_colour {}
-
- if [array exists tagvalues] {
- foreach item [array names tagvalues] {
- if [string match $tagvalues($item) $revnum] {
- if [info exists cvscfg(dotcolour,$item)] {
- lappend return_colour $cvscfg(dotcolour,$item)
- #puts "Found a dot coloured $cvscfg(dotcolour,$item) on tag $item for revision $revnum"
- }
- }
- }
- }
- return $return_colour
- }
-
- proc logcanvas_draw_box {logcanvas revnum revwho revdate revcomment} {
- #
- # Draws a box containing a revision of a file.
- #
- global cvscanv
-
- set versions [split $revnum "."]
- set numvers [llength $versions]
-
- switch -exact -- $numvers {
- 2 {
- # Remember where the new box is going.
- set cvscanv(posx$revnum) $cvscanv(nextx)
- set cvscanv(posy$revnum) $cvscanv(nexty)
- # draw a box
- logcanvas_rectangle $logcanvas $revnum $revwho $revdate $revcomment \
- $cvscanv(nextx) $cvscanv(nexty)
- # Position the next box.
- set cvscanv(nextx) $cvscanv(indx)
- set cvscanv(nexty) [expr $cvscanv(nexty) + $cvscanv(gapy)]
- }
- 4 {
- # Have we seen this branch before?
- set branchid [join [lrange $versions 0 2] "."]
- if {[lsearch -exact $cvscanv(branches) $branchid] == -1} {
- # No
- lappend cvscanv(branches) $branchid
- incr cvscanv(indents)
- }
- # x.y.z.u -- version x.y must already exist, so find out where it is.
- set backrevnum [join [lrange $versions 0 1] "."]
- set thisx [expr $cvscanv(gapx) * $cvscanv(indents) + \
- $cvscanv(indx) ]
- set thisy [expr $cvscanv(posy$backrevnum) - \
- $cvscanv(gapy) * [lindex $versions 3]]
- # Remember where the new box is going.
- set cvscanv(posx$revnum) $thisx
- set cvscanv(posy$revnum) $thisy
- # Draw the box
- logcanvas_rectangle $logcanvas $revnum $revwho $revdate $revcomment \
- $thisx $thisy
- # Draw a connecting line.
- if {[lindex $versions [expr $numvers - 1]] == "1"} {
- $logcanvas.canvas create line \
- [expr $cvscanv(boxx) / 2 + $thisx] \
- [expr $cvscanv(boxy) + $thisy] \
- [expr $cvscanv(boxx) + $cvscanv(posx$backrevnum)] \
- [expr $cvscanv(boxy) / 2 + $cvscanv(posy$backrevnum)]
- }
- }
- # Yes I know this is ugly -- just a cut and paste of the previous
- # section -- fix this soon.
- 6 {
- # Have we seen this branch before?
- set branchid [join [lrange $versions 0 4] "."]
- if {[lsearch -exact $cvscanv(branches) $branchid] == -1} {
- # No
- lappend cvscanv(branches) $branchid
- incr cvscanv(indents)
- }
- # x.y.z.u -- version x.y must already exist, so find out where it is.
- set backrevnum [join [lrange $versions 0 3] "."]
- set thisx [expr $cvscanv(gapx) * $cvscanv(indents) + \
- $cvscanv(indx) ]
- set thisy [expr $cvscanv(posy$backrevnum) - \
- $cvscanv(gapy) * [lindex $versions 5]]
- # Remember where the new box is going.
- set cvscanv(posx$revnum) $thisx
- set cvscanv(posy$revnum) $thisy
- # Draw the box
- logcanvas_rectangle $logcanvas $revnum $revwho $revdate $revcomment \
- $thisx $thisy
- # Draw a connecting line.
- if {[lindex $versions [expr $numvers - 1]] == "1"} {
- $logcanvas.canvas create line \
- [expr $cvscanv(boxx) / 2 + $thisx] \
- [expr $cvscanv(boxy) + $thisy] \
- [expr $cvscanv(boxx) + $cvscanv(posx$backrevnum)] \
- [expr $cvscanv(boxy) / 2 + $cvscanv(posy$backrevnum)]
- }
- }
- }
-
- }
-
- proc logcanvas_rectangle {logcanvas revnum revwho revdate revcomment x y} {
- #
- # Breaks out some of the code from the logcanvas_draw_box procedure.
- #
- global cvscanv
-
- set versions [split $revnum "."]
- set numvers [llength $versions]
-
- # draw a box
- $logcanvas.canvas create rectangle \
- $x $y [expr $x + $cvscanv(boxx)] [expr $y + $cvscanv(boxy)] \
- -width 3 \
- -outline [logcanvas_box_colour $revnum] \
- -tags v$revnum
-
- # Make sure the scrolling region is big enough
- if {$cvscanv(xlow) > $x} {
- set cvscanv(xlow) $x
- }
- if {$cvscanv(ylow) > $y} {
- set cvscanv(ylow) $y
- }
- if {$cvscanv(xhigh) < [expr $x + $cvscanv(boxx)]} {
- set cvscanv(xhigh) [expr $x + $cvscanv(boxx) + 10]
- }
- if {$cvscanv(yhigh) < [expr $y + $cvscanv(boxy)]} {
- set cvscanv(yhigh) [expr $y + $cvscanv(boxy) + 10]
- }
- $logcanvas.canvas configure \
- -scrollregion "$cvscanv(xlow) $cvscanv(ylow) $cvscanv(xhigh) $cvscanv(yhigh)"
-
- # Put the version number in the box
- $logcanvas.canvas create text \
- [expr $x + 4] [expr $y + 2] \
- -anchor nw -text $revnum \
- -fill [logcanvas_box_colour $revnum] \
- -tags v$revnum
- $logcanvas.canvas create text \
- [expr $x + 4] [expr $y + 14] \
- -anchor nw -text $revwho \
- -fill [logcanvas_box_colour $revnum] \
- -tags v$revnum
-
- # Put some dots in the box if necessary.
- set dotnum 0
- foreach dotcolour [logcanvas_dot_colour $revnum] {
- set dotx [expr $x + $cvscanv(boxx) - 8]
- set doty [expr $dotnum * 6 + $y + 3]
- #puts "Drawing a dot at $dotx $doty coloured $dotcolour"
- $logcanvas.canvas create oval \
- $dotx $doty [expr $dotx + 5] [expr $doty + 5] \
- -fill $dotcolour \
- -outline ""
- incr dotnum
- }
-
- # Bind to the tag.
- $logcanvas.canvas bind v$revnum <ButtonPress-1> \
- "$logcanvas.tvers1 delete 0 end
- $logcanvas.tvers1 insert end $revnum
- $logcanvas.twho1 configure -text $revwho
- $logcanvas.tdate1 configure -text $revdate
- $logcanvas.tcomment1 delete 1.0 end
- $logcanvas.tcomment1 insert end \"$revcomment\""
- $logcanvas.canvas bind v$revnum <ButtonPress-3> \
- "$logcanvas.tvers2 delete 0 end
- $logcanvas.tvers2 insert end $revnum
- $logcanvas.twho2 configure -text $revwho
- $logcanvas.tdate2 configure -text $revdate
- $logcanvas.tcomment2 delete 1.0 end
- $logcanvas.tcomment2 insert end \"$revcomment\""
- # Draw a connecting line. Up if X.0, nowhere if X.1, down if > X.1
- # This should work for most version starting points.
- if {[lindex $versions [expr $numvers - 1]] == "0"} {
- $logcanvas.canvas create line \
- [expr $cvscanv(boxx) / 2 + $x] \
- [expr $y - $cvscanv(gapy) + $cvscanv(boxy)] \
- [expr $cvscanv(boxx) / 2 + $x] \
- [expr $y]
- } elseif {[lindex $versions [expr $numvers - 1]] != "1"} {
- $logcanvas.canvas create line \
- [expr $cvscanv(boxx) / 2 + $x] \
- [expr $cvscanv(boxy) + $y] \
- [expr $cvscanv(boxx) / 2 + $x] \
- [expr $cvscanv(gapy) + $y]
- }
- }
-
- proc logcanvas_view {logcanvas} {
- #
- # Views the selected version.
- #
- set ver1 [$logcanvas.tvers1 get]
- set localfile [$logcanvas.tlocalfile get]
-
- if {$localfile != "no file"} {
- cvs_view_r $ver1 $localfile
- } else {
- set fname [$logcanvas.tfname get]
- rcs_fileview $fname $ver1
- }
- }
-
- proc logcanvas_diff {logcanvas} {
- #
- # Diffs two versions.
- #
- set ver1 [$logcanvas.tvers1 get]
- set ver2 [$logcanvas.tvers2 get]
- set localfile [$logcanvas.tlocalfile get]
-
- if {$localfile != "no file"} {
- cvs_diff_r $ver1 $ver2 $localfile
- } else {
- set fname [$logcanvas.tfname get]
- rcs_filediff $fname $ver1 $ver2
- }
- }
-
- proc logcanvas_join {localfile logcanvas} {
- #
- # Joins a branch version to the head version.
- #
- set ver1 [$logcanvas.tvers1 get]
- set versions [split $ver1 "."]
- set numvers [llength $versions]
- if {$numvers < 4} {
- cvserror "Please select a branch version for this function!"
- return 1
- }
-
- cvs_join $localfile $ver1
- }
-
- proc logcanvas_delta {localfile logcanvas} {
- #
- # Merges changes in the delta between two versions to the head
- # version.
- #
- set ver1 [$logcanvas.tvers1 get]
- set ver2 [$logcanvas.tvers2 get]
-
- cvs_delta $localfile $ver1 $ver2
- }
-